import { asyncRoutes, constantRoutes } from '@/router'
import { getPermissions } from '@/api/account'

/**
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
// 检查用户是否有访问某个路由的权限
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some((role) => route.meta.roles.includes(role))
  } else {
    return true
  }
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
// 根据角色筛选过滤路由，最终生成路由
// 递归过滤异步路由表，只保留用户有权限访问的路由。
export function filterAsyncRoutes(routes, roles) {
  const res = []

  routes.forEach((route) => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

const state = {
  routes: [],
  addRoutes: [],
  // 全局存储菜单权限
  permissions: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  },
  // 添加更新菜单权限方法
  SET_PERMISSIONS: (state, permissions) => {
    state.permissions = permissions
  }
}

// 用于根据用户的权限生成和管理动态路由 这是一个Vuex action，接收两个参数
// commit：用于提交mutations来更改Vuex状态。 roles：用户的角色信息。
// 1、路由定义代码中，我们是没有定义mate:{roles:[]}的，因为我们系统角色是可以灵活添加的，不是固定的。所以vue-router官方的方案不适合我们的需求。
// 2、我们可以通过设置路由元素属性hidden，来实现路由的显示隐藏。hidden：true为隐藏，hidden：false为显示。
const actions = {
  generateRoutes({ commit }, roles) {
    return new Promise((resolve) => {
      let accessedRoutes
      getPermissions().then((res) => {
        console.log(999, res)

        const permissions = res
        // 初始化 默认隐藏所有菜单
        for (const routeIndex in asyncRoutes) {
          asyncRoutes[routeIndex].hidden = true
          const childrens = asyncRoutes[routeIndex].children
          for (const childrenIndex in childrens) {
            childrens[childrenIndex].hidden = true
          }
        }

        // 开启有权限的菜单
        for (const routeIndex in asyncRoutes) {
          const childrens = asyncRoutes[routeIndex].children
          for (const childrenIndex in childrens) {
            const child = childrens[childrenIndex]
            // 检查当前子路由是否在权限列表中 根据状态判断status显示隐藏
            if (permissions.find((x) => x.code === child.name) !== null) {
              child.hidden = false
              asyncRoutes[routeIndex].hidden = false
            }
          }
        }
        accessedRoutes = asyncRoutes
        // 调用Vuex的commit方法，触发名为SET_ROUTES的mutation，将生成的路由存储在Vuex的状态中
        commit('SET_ROUTES', accessedRoutes)
        commit('SET_PERMISSIONS', permissions)
        resolve(accessedRoutes)
      })
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
